/*
 *  Copyright 2015-2016, RenGu Technology (BeiJing) Co., Ltd.
 *  All right reserved.
 *
 *  THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF RENGU TECHNOLOGY (BeiJing) CO., LTD.
 *
 *  THE CONTENTS OF THIS FILE MAY NOT BE DISCLOSED TO THIR PARTIES,
 *  COPIED OR DUPLICATED IN ANY FORM, IN WHOLE OR IN PART,
 *  WITHOUT THE PRIOR WRITTEN PERMISSION OF RENGU TECHNOLOGY (BeiJing) CO., LTD.
 *
 *  IntelliStatisticsChnlService.java
 *
 *  Edit History:
 *      lizhangtao Created on 2022年01月11日
 *
 */
package cc.rengu.igas.route.core.service.trans;

import cc.rengu.igas.route.common.constant.SmartRouteParamConstant;
import cc.rengu.igas.route.common.enums.RespCodeEnum;
import cc.rengu.igas.route.common.enums.SmartRouteRspEnums;
import cc.rengu.igas.route.facade.bean.StatisticsCalChannelInfo;
import cc.rengu.igas.route.facade.bean.StatisticsCalInfo;
import cc.rengu.igas.route.facade.request.IntelliStatisticsChnlRequest;
import cc.rengu.igas.route.facade.response.IntelliStatisticsChnlResponse;
import cc.rengu.oltp.service.base.RadpService;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.enums.TransStatusEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.utility.util.ConvertUtil;
import cc.rengu.oltp.utility.util.RedisUtil;
import cc.rengu.oltp.utility.util.XmlTreeUtil;
import cc.rengu.utility.base.StringUtil;
import cc.rengu.utility.reflect.JsonUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 路由分析监控
 *
 * @author lizhangtao
 * @version 1.0
 * @date 2022/1/11
 */
public class IntelliStatisticsChnlService extends RadpService {
    /**
     * Biz init int.
     *
     * @param s the s
     * @return the int
     */
    @Override
    protected int bizInit(String s) {
        return 0;
    }

    /**
     * Biz process int.
     *
     * @param s the s
     * @param i the
     * @return the int
     */
    @Override
    protected int bizProcess(String s, int i) {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        try {
            IntelliStatisticsChnlRequest request = new IntelliStatisticsChnlRequest();
            ConvertUtil.convertOutput(request);
            //参数为空判断
            if (StringUtil.isNullorEmpty(request.getHeader().getInstId()) ||
                    StringUtil.isNullorEmpty(request.getHeader().getSrcSysId()) ||
                    StringUtil.isNullorEmpty(request.getHeader().getChanlId())) {
                rglog.error("必须输入机构号<{}>，发起系统<{}>、渠道号<{}>", request.getHeader().getInstId(),
                        request.getHeader().getSrcSysId(), request.getHeader().getChanlId());
                throw new BizException(SmartRouteRspEnums.MSG_VALID_CHECK_ERROR.getRespCode(), SmartRouteRspEnums.MSG_VALID_CHECK_ERROR.getRespDesc());
            }

            xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.SRC_SYS_ID, request.getHeader().getSrcSysId());
            xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM, request.getHeader().getTraceNo());
            xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TRANS_TIME, request.getHeader().getTransTime());
            xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TRANS_DATE, request.getHeader().getTransDate());

            //从redis取通道及交易笔数，计算命中率
            //key: ROUT_MONITOR+qryTxnNum（查询的交易类型）+qryTBizType（查询的原业务分类）
            String key = SmartRouteParamConstant.ROUT_MONITOR + request.getQryTxnNum() + request.getQryBizType();
            Map<String, String> allData = RedisUtil.hashGetAll(key);
            IntelliStatisticsChnlResponse response = new IntelliStatisticsChnlResponse();
            response.setHeader(request.getHeader());
            List<StatisticsCalInfo> statisticsCalInfoList = new ArrayList<>();
            response.setStatisticsCalInfoList(statisticsCalInfoList);
            int sum = 0;
            for (Map.Entry<String, String> entry : allData.entrySet()) {
                sum += Integer.parseInt(entry.getValue());
            }

            rglog.info("redis allData:[{}]", JsonUtil.toJson(allData));
            for (Map.Entry<String, String> entry : allData.entrySet()) {
                StatisticsCalInfo statisticsCalInfo = new StatisticsCalInfo();
                StatisticsCalChannelInfo statisticsCalChannelInfo = new StatisticsCalChannelInfo();
                String key1 = entry.getKey();
                String[] array = key1.split("\\|");
                //field: dstChannelId（通道产品编码）+|+channelDesc（通道描述）+|+feeWeight（费用权重）+|+stressWeight（压力权重）+|+succRateWeight（交易成功率权重）+|+timeCostWeight（响应时间权重）
                statisticsCalChannelInfo.setDstChannelId(array[0]);
                statisticsCalChannelInfo.setChannelDesc(array[1]);
                statisticsCalChannelInfo.setSum(entry.getValue());
                statisticsCalChannelInfo.setHit(String.format("%.2f", Double.parseDouble(entry.getValue()) / sum * 100));

                String feeWeignt = array[2];
                String stressWeight = array[3];
                String succRateWeight = array[4];
                String timeCostWeight = array[5];
                String groupKey = feeWeignt + stressWeight + succRateWeight + timeCostWeight;
                Optional<StatisticsCalInfo> statisticsCalInfoOpt = statisticsCalInfoList.stream().filter(item1 -> groupKey.equals(fetchGroupKey(item1))).findFirst();
                if (statisticsCalInfoOpt.isPresent()) {
                    List<StatisticsCalChannelInfo> statisticsCalChannelInfos = statisticsCalInfoOpt.get().getStatisticsCalChannelInfoList();
                    statisticsCalChannelInfos.add(statisticsCalChannelInfo);
                } else {
                    List<StatisticsCalChannelInfo> statisticsCalChannelInfoList = new ArrayList<>();
                    statisticsCalChannelInfoList.add(statisticsCalChannelInfo);

                    statisticsCalInfo.setFeeWeight(feeWeignt);
                    statisticsCalInfo.setStressWeight(stressWeight);
                    statisticsCalInfo.setSuccRateWeight(succRateWeight);
                    statisticsCalInfo.setTimeCostWeight(timeCostWeight);
                    statisticsCalInfo.setStatisticsCalChannelInfoList(statisticsCalChannelInfoList);
                    statisticsCalInfoList.add(statisticsCalInfo);
                }
            }

            response.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
            response.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
            response.setStatus(TransStatusEnum.TRANS_SUCC.getStatus());
            ConvertUtil.convertInput(response);
        } catch (BizException e) {
            try {
                xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.RESP_CODE, e.getCode());
                xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.RESP_DESC, e.getMessage());
            } catch (Exception e1) {
                rglog.error(StringUtil.ExceptionToString(e1));
            }
        } catch (Exception e) {
            rglog.error(StringUtil.ExceptionToString(e));
            try {
                xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.RESP_CODE, SmartRouteRspEnums.TRANS_FAIL.getRespCode());
                xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.RESP_DESC, SmartRouteRspEnums.TRANS_FAIL.getRespDesc());
            } catch (Exception e1) {
                rglog.error(StringUtil.ExceptionToString(e1));
            }
        }
        return 0;
    }

    /**
     * Biz terminate int.
     *
     * @param s the s
     * @return the int
     */
    @Override
    protected int bizTerminate(String s) {
        return 0;
    }


    /**
     * 匹配分组key
     *
     * @param statisticsCalInfo 统计信息
     * @return 分组key
     */
    private static String fetchGroupKey(StatisticsCalInfo statisticsCalInfo) {
        return statisticsCalInfo.getFeeWeight() + statisticsCalInfo.getStressWeight() +
                statisticsCalInfo.getSuccRateWeight() + statisticsCalInfo.getTimeCostWeight();
    }
}
